package com.fjwt.gz.service.activity.coupon.acte006;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.fjwt.gz.components.mq.websocket.server.MinProgramWsChannelServer;
import com.fjwt.gz.core.cache.RedisUtil;
import com.fjwt.gz.core.constants.Constants;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.bo.ActivityAwardAndSettingBo;
import com.fjwt.gz.db.bo.ActivityUserTimesBO;
import com.fjwt.gz.db.dto.FansActivityDTO;
import com.fjwt.gz.db.entity.*;
import com.fjwt.gz.db.vo.ActivityAwardVO;
import com.fjwt.gz.db.vo.AgentAppVO;
import com.fjwt.gz.db.vo.ExportAwardVO;
import com.fjwt.gz.service.activity.BaseActivityDTO;
import com.fjwt.gz.service.activity.BaseActivityService;
import com.fjwt.gz.service.impl.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 扫码派券------
 */
@Slf4j
@Service
public class ACTE006Service extends BaseActivityService<Object> {

    private static String logPrefix = "【扫码派券】";

    @Autowired
    private ActivityAwardService activityAwardService;
    @Autowired
    private ActivitySettingService activitySettingService;
    @Autowired
    private FansAwardService fansAwardService;
    @Autowired
    private AgentInfoService agentInfoService;
    @Autowired
    private AwardAgentService awardAgentService;
    @Autowired
    private SendAwardService sendAwardService;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private FansService fansService;
    @Autowired
    private AgentAppService agentAppService;
    @Autowired
    private FansAgentService fansAgentService;
    @Autowired
    private AwardSettingService awardSettingService;
    @Autowired
    private MinProgramWsChannelServer wsChannelServer;


    /**
     * 新建活动
     */
    @Override
    public void add(BaseActivityDTO activityDTO) {
        log.info("新增ACTE006的活动");
        super.add(activityDTO);
    }

    /**
     * 修改活动
     */
    @Override
    public void update(BaseActivityDTO activityDTO) {
        log.info("更新ACTE006的活动");
        super.update(activityDTO);
    }

    /**
     * 删除活动
     */
    @Override
    public void delete(Long activityId) {
        log.info("删除ACTE006的活动");
        super.delete(activityId);
    }

    /**
     * 活动详情--pc
     */
    @Override
    public BaseActivityDTO detail(Long activityId) {
        log.info("查看ACTE006的活动详情");
        BaseActivityDTO baseActivityDetailsVO = super.detail(activityId);
        return baseActivityDetailsVO;
    }

    /**
     * 参与活动
     */
    @Override
    public ActivityAwardVO takePartIn(FansActivityDTO fansActivityDTO) {
        log.info("进入扫码派券活动");
        super.takePartIn(fansActivityDTO);
        Long fansId = fansActivityDTO.getFansId();
        Long activityId = fansActivityDTO.getActivityId();
        //查询用户信息
        FansEntity fansEntity = fansService.getById(fansId);
        //查询活动信息

        ActivityEntity activityEntity = activityService.getById(activityId);
        //查询appid
        AgentAppVO agentApp = agentAppService.getAgentApp(activityId);
        JSONObject jsonObject = activitySettingService.checkActivitySetting(fansEntity, agentApp.getAppId(), redisOutTime, activityEntity);
        // 进行发券处理
        List<ActivityAwardAndSettingBo> activityAwardList = awardSettingService.getActivityAwardList(activityId, redisOutTime);
        // 校验用户奖品限制
        Map<Long, JSONObject> awardUserTimesJsonMap = new HashMap<>();
        for (ActivityAwardAndSettingBo activityAwardAndSettingBo : activityAwardList) {
            JSONObject awardUserTimesJson = awardSettingService.AwardSettingRule(fansId, activityEntity.getAgentNo(), activityAwardAndSettingBo);
            if (ObjectUtils.isNotEmpty(awardUserTimesJson)) {
                awardUserTimesJsonMap.put(activityAwardAndSettingBo.getAwardId(), awardUserTimesJson);
            }
        }

        // 卡券分配map
        Map<Long, AwardAgentEntity> awardIdAgentMap = new HashMap<>();
        if (ObjectUtils.isNotEmpty(activityAwardList) && ObjectUtils.isNotEmpty(fansActivityDTO.getAgentNo())) {
            AgentInfoEntity agentInfo = agentInfoService.getById(fansActivityDTO.getAgentNo());
            if (ObjectUtils.isEmpty(agentInfo)) {
                throw new BizException("当前机构异常");
            }
            Set<Long> awardIds = activityAwardList.stream()
                    .filter(item -> Integer.valueOf(1).equals(item.getIsAllocation()))
                    .map(ActivityAwardAndSettingBo::getAwardId)
                    .collect(Collectors.toSet());
            // 查询当前客户经理所属机构是否还有剩余数量
            if (!awardIds.isEmpty()) {
                List<AwardAgentEntity> awardAgentEntities = awardAgentService.list(AwardAgentEntity.gw().in(AwardAgentEntity::getAwardId, awardIds).eq(AwardAgentEntity::getAgentNo, agentInfo.getAgentNo()).eq(AwardAgentEntity::getAwardType, 0));
                // 如果是四级机构查询是否有同级机构分配过
                if (4 == agentInfo.getLevel()) {
                    List<AwardAgentEntity> awardAgentEntities3 = awardAgentService.list(AwardAgentEntity.gw().in(AwardAgentEntity::getAwardId, awardIds).eq(AwardAgentEntity::getAgentNo3, agentInfo.getAgentNo3()).eq(AwardAgentEntity::getAwardType, 0));
                    // 如果没有分配过就显示三级，分配过同级或者三级也没分配就不显示
                    Map<Long, List<AwardAgentEntity>> awardAgentEntities3Map = awardAgentEntities3.stream().collect(Collectors.groupingBy(AwardAgentEntity::getAwardId));
                    for (List<AwardAgentEntity> value : awardAgentEntities3Map.values()) {
                        if (value.size() == 1) {
                            awardAgentEntities.addAll(value);
                        }
                    }
                }
                if (!awardAgentEntities.isEmpty()) {
                    awardIdAgentMap = awardAgentEntities.stream().collect(Collectors.toMap(AwardAgentEntity::getAwardId, Function.identity()));

                    // 如果是二三级机构判断下已分配数量
                    List<AwardAgentEntity> awardAgentEntityList = new ArrayList<>();
                    if (3 == agentInfo.getLevel()) {
                        // 查询四级已分配数量
                        awardAgentEntityList = awardAgentService.list(AwardAgentEntity.gw()
                                .in(AwardAgentEntity::getAwardId, awardIds)
                                .eq(AwardAgentEntity::getAgentNo3, agentInfo.getAgentNo())
                                .eq(AwardAgentEntity::getAwardType, 0));
                    } else if (2 == agentInfo.getLevel()) {
                        // 查询三级已分配数量
                        awardAgentEntityList = awardAgentService.list(AwardAgentEntity.gw().in(AwardAgentEntity::getAwardId, awardIds).eq(AwardAgentEntity::getAgentNo2, agentInfo.getAgentNo()).eq(AwardAgentEntity::getAwardType, 0));
                    }
                    if (!awardAgentEntityList.isEmpty()) {
                        Map<Long, Integer> awardIdSumMap = awardAgentEntityList.stream().filter(item -> !item.getAgentNo().equals(agentInfo.getAgentNo())).collect(Collectors.groupingBy(AwardAgentEntity::getAwardId, Collectors.summingInt(AwardAgentEntity::getNum)));
                        if (!awardIdSumMap.entrySet().isEmpty()) {
                            if (awardIdSumMap.entrySet().iterator().next().getValue() + awardAgentEntities.get(0).getNumConsume() >= awardAgentEntities.get(0).getNum()) {
                                throw new BizException("当前机构无剩余派券数量");
                            }
                        }
                    }
                }
            }
        }
        FansAgentEntity one = fansAgentService.lambdaQuery()
                .eq(FansAgentEntity::getFansId, fansActivityDTO.getAgentFansId())
                .eq(FansAgentEntity::getAppId, fansActivityDTO.getAppId())
                .eq(FansAgentEntity::getIsDeleted, 0).one();
        for (ActivityAwardAndSettingBo activityAwardAndSettingBo : activityAwardList) {
            if (activityAwardAndSettingBo.getIsAllocation() !=null && 1 == activityAwardAndSettingBo.getIsAllocation()) {
                if (!awardIdAgentMap.containsKey(activityAwardAndSettingBo.getAwardId())) {
                    throw new BizException("当前机构无剩余派券数量");
                }
                AwardAgentEntity awardAgentEntity = awardIdAgentMap.get(activityAwardAndSettingBo.getAwardId());
                if (awardAgentEntity.getNumConsume() >= awardAgentEntity.getNum()) {
                    throw new BizException("当前机构无剩余派券数量");
                }
                // 减去机构库存数量
                AwardAgentEntity updateAwardAgentEntity = new AwardAgentEntity().setAwardAgentId(awardAgentEntity.getAwardAgentId()).setNumConsume(awardAgentEntity.getNumConsume() + 1);
                boolean falag = awardAgentService.updateById(updateAwardAgentEntity);
                if (falag == false) {
                    throw new BizException("活动太火爆了，请稍后再试!");
                }
            }
//            // 增加获奖记录
            Long fansAwardId = sendAwardService.sendCouponOrGoods(fansActivityDTO.getFansId(),fansActivityDTO.getAppId(),activityAwardAndSettingBo, activityEntity.getPayAuthId(), null,true,
                    fansActivityDTO.getExtJson());
            JSONObject awardUserTimesJson = awardUserTimesJsonMap.get(activityAwardAndSettingBo.getAwardId());
            //更新Redis中参与的次数
            awardSettingService.updateAwardLimitCache(awardUserTimesJson, redisOutTime);
            if (StringUtils.isNotEmpty(fansActivityDTO.getAgentNo()) && null != fansAwardId) {
                AgentInfoEntity agentInfo = agentInfoService.getById(fansActivityDTO.getAgentNo());
                if (null != agentInfo) {
                    FansAwardEntity awardEntity = new FansAwardEntity();
                    awardEntity.setFansAwardId(fansAwardId);
                    awardEntity.setSendAgentNo(agentInfo.getAgentNo());
                    awardEntity.setSendAgentNo1(agentInfo.getAgentNo1());
                    awardEntity.setSendAgentNo2(agentInfo.getAgentNo2());
                    awardEntity.setSendAgentNo3(agentInfo.getAgentNo3());
                    awardEntity.setSendAgentNo4(agentInfo.getAgentNo4());
                    if (one != null){
                        awardEntity.setSendAgentEmployeeId(one.getAgentEmployeeId());
                    }
                    fansAwardService.updateById(awardEntity);
                }
//                wsChannelServer.convertAndSend(String.valueOf(fansId), fansActivityDTO.getAppId(), "扫码派券", "派券成功！");
//            }else{
//                wsChannelServer.convertAndSend(String.valueOf(fansId), fansActivityDTO.getAppId(), "扫码派券", "派券失败！");
            }
            log.info("增加获奖记录返回的fansAwardId:{}", fansAwardId);
        }

        //重新放置活动奖品配置缓存
        if (!activityAwardList.isEmpty()) {
            String activityAwardKey = String.format("%s%s:%s", Constants.REDIS_ACTIVITY.FILENAME, fansActivityDTO.getActivityId(), Constants.REDIS_ACTIVITY.AWARD);
            RedisUtil.set(activityAwardKey, activityAwardList, redisOutTime, TimeUnit.MILLISECONDS);
            log.info("活动奖品列表，修改奖品中的当前周期性领取次数数据，redisKey:{},redisValue:{},redisOutTime:{},TimeUnit:{}", activityAwardKey, JSONUtil.toJsonStr(activityAwardList), redisOutTime, "TimeUnit.MILLISECONDS");
        }

        //更新Redis中参与的次数
        ActivityUserTimesBO activityUserTimesBO = jsonObject.getObject("activityUserTimesBO", ActivityUserTimesBO.class);
        if (ObjectUtils.isNotEmpty(activityUserTimesBO)){
            activitySettingService.updateRedisParticipateNum(jsonObject.getString("currentTimesKey"), activityUserTimesBO, redisOutTime);
        }
        Boolean userJoinScoreValue = jsonObject.getObject("userJoinScoreValue", Boolean.class);
        if (ObjectUtils.isNotEmpty(userJoinScoreValue)){
            RedisUtil.set(jsonObject.getString("userJoinScoreKey"), userJoinScoreValue, redisOutTime, TimeUnit.MILLISECONDS);
        }
        return activityAwardService.toUserData(null);
    }

    @Override
    public void shareRun(JSONObject jsonObject) {

    }

}
